#include "../Include/BackBuffer.h"

BackBuffer::BackBuffer( HWND hWnd, INT width, INT height )
	: m_hWnd( hWnd ), m_appWidth( width ), m_appHeight( height )
{
	PSX_ThrowAssert( width, "Width specified 0." );
	PSX_ThrowAssert( height, "Height specified 0." );

	// Get device context of hWnd
	HDC hWndDC = ::GetDC( hWnd );

	// Create Compatible device context with the window
	m_hdc = CreateCompatibleDC( hWndDC );

	// Create surface compatible with hWndDC. This will be the surface
	// we will render onto.
	m_hSurface = CreateCompatibleBitmap( hWndDC, width, height );

	// Don't forget to release back the hWndDC
	ReleaseDC( hWnd, hWndDC );

	// Store surface and make sure to save default surface.
	// We need to restore the old surface back when we're done using
	// the back buffer.
	m_hOldSurface = (HBITMAP)SelectObject( m_hdc, m_hSurface );

	HBRUSH white =  (HBRUSH)GetStockObject( WHITE_BRUSH );
	HBRUSH oldBrush = (HBRUSH)SelectObject( m_hdc, white );

	// This clears the back buffer using the white brush
	Rectangle( m_hdc, 0, 0, m_appWidth, m_appHeight );

	// We're all done. Restore brush back.
	SelectObject( m_hdc, oldBrush );
}

BackBuffer::~BackBuffer()
{
	SelectObject( m_hdc, m_hOldSurface );
	DeleteObject( m_hSurface );
	DeleteDC( m_hdc );
}

// Call this function when you want it to present to
// the Fron buffer.
void BackBuffer::Present( void )
{
	HDC hWndDC = ::GetDC( m_hWnd );

	BitBlt( hWndDC, 0, 0, m_appWidth, m_appHeight, m_hdc, 0, 0, SRCCOPY );

	// Always free hWndDC when done using.
	ReleaseDC( m_hWnd, hWndDC );
}

// Clears the screen
void BackBuffer::Clear( const UINT color /*= 0*/ )
{
	HBRUSH oldDC = (HBRUSH)SelectObject( m_hdc, GetStockObject( BLACK_BRUSH ) );
	Rectangle( m_hdc, 0, 0, m_appWidth, m_appHeight );
	SelectObject( m_hdc, oldDC );
}
